﻿using System.Collections.Generic;
using ManoMachine.Assembler.Mnemonics.Descriptors;

namespace ManoMachine.Assembler.Mnemonics
{
    static class MnemonicsDictionary
    {
        static readonly Dictionary<string, MnemonicDescriptor> Mnemonics = new Dictionary<string, MnemonicDescriptor>();

        static MnemonicsDictionary()
        {
            // MRI
            AddDescriptor(new MRIDescriptor("AND", 0x0));
            AddDescriptor(new MRIDescriptor("ADD", 0x1));
            AddDescriptor(new MRIDescriptor("LDA", 0x2));
            AddDescriptor(new MRIDescriptor("STA", 0x3));
            AddDescriptor(new MRIDescriptor("BUN", 0x4));
            AddDescriptor(new MRIDescriptor("BSA", 0x5));
            AddDescriptor(new MRIDescriptor("ISZ", 0x6));
            
            // RRI
            AddDescriptor(new RRIDescriptor("CLA", 0x7800));
            AddDescriptor(new RRIDescriptor("CLE", 0x7400));
            AddDescriptor(new RRIDescriptor("CMA", 0x7200));
            AddDescriptor(new RRIDescriptor("CME", 0x7100));
            AddDescriptor(new RRIDescriptor("CIR", 0x7080));
            AddDescriptor(new RRIDescriptor("CIL", 0x7040));
            AddDescriptor(new RRIDescriptor("INC", 0x7020));
            AddDescriptor(new RRIDescriptor("SPA", 0x7010));
            AddDescriptor(new RRIDescriptor("SNA", 0x7008));
            AddDescriptor(new RRIDescriptor("SZA", 0x7004));
            AddDescriptor(new RRIDescriptor("SZE", 0x7002));
            AddDescriptor(new RRIDescriptor("HLT", 0x7001));

            // IOI
            AddDescriptor(new IOIDescriptor("INP", 0xF800));
            AddDescriptor(new IOIDescriptor("OUT", 0xF400));
            AddDescriptor(new IOIDescriptor("SKI", 0xF200));
            AddDescriptor(new IOIDescriptor("SKO", 0xF100));
            AddDescriptor(new IOIDescriptor("ION", 0xF080));
            AddDescriptor(new IOIDescriptor("IOF", 0xF040));

            // PSI
            AddDescriptor(new PSIDescriptor("ORG", true));
            AddDescriptor(new PSIDescriptor("END", false));
            AddDescriptor(new PSIDescriptor("DEC", true));
            AddDescriptor(new PSIDescriptor("HEX", true));
        }

        private static void AddDescriptor(MnemonicDescriptor descriptor)
        {
            string nameUpper = descriptor.Name.ToUpper();
            Mnemonics.Add(nameUpper, descriptor);
        }

        public static MnemonicDescriptor GetDescriptor(string mnemonicCode)
        {
            string mnemonicCodeUpper = mnemonicCode.ToUpper();
            if (!Mnemonics.ContainsKey(mnemonicCodeUpper)) return null;
            MnemonicDescriptor mnemonicDescriptor = Mnemonics[mnemonicCodeUpper];
            return mnemonicDescriptor;
        }
    }
}
